package com.cn.lp.export.server.controller;

import com.cn.lp.export.server.ExportResultCodes;
import com.cn.lp.export.server.base.context.BaseController;
import com.cn.lp.export.server.base.context.CommandResult;
import com.cn.lp.export.server.base.context.ExportExceptionCreator;
import com.cn.lp.export.server.entity.ExportService;
import com.cn.lp.export.server.entity.ExportStatus;
import com.cn.lp.export.server.entity.ExportTask;
import com.cn.lp.export.server.entity.ExportTaskDao;
import com.cn.lp.export.server.entity.executor.ExportExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
import org.springframework.web.bind.annotation.*;

import java.util.concurrent.CompletableFuture;

/**
 * Description: 请描述你的文件
 *
 * @author wuqirong
 * @date 2020-10-16
 * <p>
 * All rights Reserved, Designed www.xiao100.com
 */
@RestController
@RequestMapping("/export")
public class ExportController implements BaseController {

    private static Logger logger = LoggerFactory.getLogger(ExportController.class);

    @Autowired
    private ExportService exportService;

    @Autowired
    private ExportTaskDao exportTaskDao;

    @Autowired
    private ExportExecutor exportExecutor;

    @PostMapping("/task/create")
    public CommandResult<CreateExportTaskResponse> createExportTask(
        @RequestBody
            CreateExportTaskRequest request
    ) {
        return succ(exportService.createExportTask(request));
    }

    //    {"taskId":"1076272301692944384","sort":1,"data":"CAET0gEHSGFzaE1hcAsLSgR0ZXN0DBMoexQMFA==","dataNum":2}
    // TODO 幂等性
    @PostMapping("/data/upload")
    public CommandResult<Boolean> uploadExportData(
        @RequestBody
            UploadExportDataRequest request) {
        // 代替分布式锁的乐观锁
        boolean reTry = true;
        while (reTry) {
            reTry = false;
            try {
                ExportStatus exportStatus = exportService.uploadExportData(request);
                if (exportStatus == ExportStatus.RUNNING) {
                    //异步提交导出任务
                    CompletableFuture.runAsync(() -> {
                        try {
                            exportExecutor.export(Long.parseLong(request.getTaskId()));
                        } catch (Exception e) {
                            logger.error(request.getTaskId() + "导出异常", e);
                        }
                    });
                }
            } catch (ObjectOptimisticLockingFailureException e) {
                reTry = true;
            } catch (DataIntegrityViolationException e) {
                throw ExportExceptionCreator.create(ExportResultCodes.UPLOAD_DATA_REPEAT, request.getTaskId(), request.getSort());
            }
        }
        return succ(true);
    }

    @PostMapping("/task/{taskId}/cancel")
    public CommandResult<Boolean> cancelTask(@PathVariable String taskId) {
        // 代替分布式锁的乐观锁
        boolean reTry = true;
        while (reTry) {
            reTry = false;
            try {
                exportService.cancelTask(Long.parseLong(taskId));
            } catch (ObjectOptimisticLockingFailureException e) {
                reTry = true;
            }
        }
        return succ(false);
    }


    @GetMapping("/task/{taskId}/status")
    public CommandResult<Integer> getTaskStatus(@PathVariable String taskId) {
        Long id = Long.parseLong(taskId);
        ExportTask exportTask = exportTaskDao.findById(id)
            .orElseThrow(() -> ExportExceptionCreator.create(ExportResultCodes.TASK_NOT_EXIST, id));
        return succ(exportTask.getExportStatus().getId());
    }

}
